package main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import common.Normalizer;
import common.Polarity;
import common.Pair;

public class Classification
{
	private ArrayList<Pair<String,String>> allMsgs;
	
	private ArrayList<Pair<String,Polarity>> results;
	
	private Parse p;
	
	public Classification() throws IOException
	{
		allMsgs = new ArrayList<Pair<String,String>>();
		results = new ArrayList<Pair<String,Polarity>>();
		
		p = new Parse();
		try 
		{
			p.ClassifyMsgs("train.txt");
		} 
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		p.Statistic();
	}
	
	public void ReadFile(String fileName) throws IOException
	{
		BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
		String line = null;
		while((line = reader.readLine()) != null)
		{
			int rPara = line.indexOf(')');
			String head = line.substring(0,rPara+1);
			
			String marque = head.contains("microsoft")? "microsoft" :
				head.contains("google")? "google" :
					head.contains("apple")? "apple" :
						head.contains("twitter")? "twitter" : null;
			
			String content = line.substring(rPara+1);
			Pair<String,String> p = new Pair<String,String>();
			p.v1 = marque;
			p.v2 = content;
			allMsgs.add(p);
		}
	}
	
	public Polarity Classify(String msg,String marque) throws IOException
	{
		ArrayList<String> words = Normalizer.GetWords(msg);
		HashMap<String, Integer> map = new HashMap<String, Integer>();
		
		for(String word: words)
		{
			if(word.equals("") || word.equals(" ") || word.equals("\t"))
				continue;
			
			word = word.toLowerCase();
			if(map.containsKey(word))
			{
				int n = map.get(word);
				map.put(word, ++n);
			}
			else
			{
				map.put(word, 1);
			}
		}
		
		double score1 = 1;
		double score2 = 1;
		double score3 = 1;
		double score4 = 1;
		Set<String> keys = map.keySet();
		for(Iterator<String> itr = keys.iterator(); itr.hasNext(); )
		{
			String word = itr.next();
			int count = map.get(word);
			
			double beta = p.GetBeta(Polarity.Irrelevant, word,marque);
			if(beta == 0.0)
				score1 += Math.log(1-beta);
			else
				score1 += count * Math.log(1+beta);
			
			beta = p.GetBeta(Polarity.Neutral, word,marque);
			if(beta == 0.0)
				score2 += Math.log(1-beta);
			else
				score2 += count * Math.log(1+beta);
			
			beta = p.GetBeta(Polarity.Positive, word,marque);
			if(beta == 0.0)
				score3 += Math.log(1-beta);
			else
				score3 += count * Math.log(1+beta);
			
			beta = p.GetBeta(Polarity.Negative, word,marque);
			if(beta == 0.0)
				score4 += Math.log(1-beta);
			else
				score4 += count * Math.log(1+beta);
		}
		
		double score = Math.max(score1, score2);
		score = Math.max(score, score3);
		score = Math.max(score, score4);
		
		Polarity p = null;
		if(score == score1)
			p = Polarity.Irrelevant;
		if(score == score2)
			p = Polarity.Neutral;
		if(score == score3)
			p = Polarity.Positive;
		if(score == score4)
			p = Polarity.Negative;
		
		return p;
	}
	
	public void ClassifyAll() throws IOException
	{
		for(int i=0; i<allMsgs.size(); ++i)
		{
			Pair<String,String> msg = allMsgs.get(i);
			Polarity p = Classify(msg.v2,msg.v1);
			Pair<String,Polarity> result = new Pair<String,Polarity>();
			result.v1 = msg.v1;
			result.v2 = p;
			
			results.add(result);
		}
	}
	
	public void PrintResult()
	{
		for(int i=0; i<results.size(); ++i)
		{
			Pair<String,Polarity> pair = results.get(i);
			System.out.println(pair.v1+"--->"+pair.v2);
		}
	}
	
	public static void main(String[] args) throws IOException
	{
		Classification c = new Classification();
		
		try 
		{
			c.ReadFile("test.txt");
		} 
		catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println(c.Classify(" Not impressed much with the new Android update. But good signs: a readable font, emphasis on design, and less nerdiness. #google","google"));
		//c.ClassifyAll();
		//c.PrintResult();
	}
}
